package com.codelab.statemachine.datapermission;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.HexValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.boot.autoconfigure.security.SecurityProperties;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class MyDataPermissionHandler {

    private RemoteRoleService remoteRoleService;
    private RemoteUserService remoteUserService;

    @SneakyThrows
    public Expression getSqlSegment1(PlainSelect plainSelect, String whereSegment)  {
        Expression where = plainSelect.getWhere();
        if(where == null){
            where = new HexValue("1=1");
        }
        log.info("开始进行权限过滤，where:{},mappedStatementId:{}",where,whereSegment);
        String className = whereSegment.substring(0,whereSegment.lastIndexOf("."));
        String methodName = whereSegment.substring(whereSegment.lastIndexOf(".")+1);
        Table fromItem = (Table) plainSelect.getFromItem();
        Alias fromItemAlias = fromItem.getAlias();
        String mainTableName = fromItemAlias==null ?fromItem.getName():fromItemAlias.getName();
        Method[] methods = Class.forName(className).getMethods();

        for(Method m : methods){
            if(Objects.equals(m.getName(),methodName)){
                UserDataPermission annotation = m.getAnnotation(UserDataPermission.class);
                if(annotation == null){
                    return where;
                }
                User user = SecurityUtils.getUser();
                Set<String> roleTypeSet = remoteRoleService.currentUserRoleType();
                DataScope scopeType = DataPermission.getScope(roleTypeSet);
                switch (scopeType){
                    case ALL:
                        return where;
                    case DEPT:
                        List<String> deptUserList = remoteUserService.listUserCodesByDeptCodes(user.getDeptCode());
                        ItemsList deptList = new ExpressionList(deptUserList.stream().map(StringValue::new).collect(Collectors.toList()));
                        InExpression inExpressiondept = new InExpression(new Column(mainTableName+".create_user"),deptList);
                        return new AndExpression(where,inExpressiondept);
                    case MYSELF:
                        EqualsTo usesEqualsTo = new EqualsTo();
                        usesEqualsTo.setLeftExpression(new Column(mainTableName+".create_user"));
                        usesEqualsTo.setRightExpression(new StringValue(user.getUserCode()));
                        return new AndExpression(where,usesEqualsTo);
                    default:
                        break;
                }

            }
        }
        where = new HexValue("1=2");
        return where;
    }

    @SneakyThrows
    public Expression getSqlSegment(PlainSelect plainSelect, String whereSegment) {
        Expression where = plainSelect.getWhere();
        if(where == null){
            where = new HexValue("1=1");
        }
        log.info("开始进行权限过滤，where:{},mappedStatementId:{}",where,whereSegment);

        String className = whereSegment.substring(0,whereSegment.lastIndexOf("."));
        String methodName = whereSegment.substring(whereSegment.lastIndexOf(".")+1);
        Table fromItem = (Table) plainSelect.getFromItem();
        Alias fromItemAlias = fromItem.getAlias();
        String mainTableName = fromItemAlias==null?fromItem.getName():fromItemAlias.getName();

        Method[] methods = Class.forName(className).getMethods();
        for(Method m : methods){
            if(Objects.equals(m.getName(),methodName)){
                UserDataPermission annotation = m.getAnnotation(UserDataPermission.class);
                if(annotation == null){
                    return where;
                }

                User user = SecurityUtils.getUser();
                EqualsTo usesEqualsTo = new EqualsTo();
                usesEqualsTo.setLeftExpression(new Column(mainTableName+".create_user"));
                usesEqualsTo.setRightExpression(new StringValue(user.getUserCode()));
                return new AndExpression(where,usesEqualsTo);
            }
        }

        where = new HexValue("1=2");
        return where;
    }
}
